package com.freewater.javabase.demo.crypto;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 最简单的AES对称加密算法：它只需要一个固定长度的密钥，固定的明文会生成固定的密文，这种一对一的加密方式会导致安全性降低，
 * 更好的方式是通过CBC模式，它需要一个随机数作为IV参数，这样对于同一份明文，每次生成的密文都不同。
 * 密钥长度是固定的128/192/256位。
 */
public class AesEcbCrypto {
    public static void main(String[] args) {

        try {
            byte[] key = "123456789abcdefg".getBytes(StandardCharsets.UTF_8);
            byte[] data = "Hello World".getBytes(StandardCharsets.UTF_8);
            byte[] encrypt = encrypt(key, data);
            System.out.println(new BigInteger(1, encrypt).toString(16));
            byte[] decrypt = decrypt(key, encrypt);
            System.out.println(new String(decrypt, Charset.forName("utf-8")));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 密钥长度是固定的128/192/256位
    public static byte[] encrypt(byte[] key, byte[] input) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKey secretKey = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return cipher.doFinal(input);
    }

    // 密钥长度是固定的128/192/256位
    public static byte[] decrypt(byte[] key, byte[] input) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        SecretKey secretKey = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        return cipher.doFinal(input);
    }
}
